package com.hzw.saas.web.app.security;

import com.hzw.saas.api.user.IUserAccountService;
import com.hzw.saas.common.security.token.MyDefaultAccessTokenConverter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.oauth2.provider.token.*;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;

import java.util.Arrays;

/**
 * 重写JWT转换器，使用公钥验证token准确性
 *
 * RsaVerifier rsaVerifier = new RsaVerifier(publicKey);
 * Jwt jwt = JwtHelper.decodeAndVerify(token, rsaVerifier);
 * System.out.println(jwt.getClaims());
 * @author sonam
 * @sine 2021/11/2 5:05 下午
 */
@Configuration
@RequiredArgsConstructor
public class AppSecurityConfig {

    private final IUserAccountService userAccountService;
    public static final String PUBLIC_KEY_PATH = "saasr2-public.txt";
    private static final String JKS_PATH = "saasr2.jks";
    private static final String KEY_PASS = "hzwsaasr2";
    private static final String KEY_STORE_ALIAS = "saasr2";

    @Bean
    @Primary
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    @Primary
    public TokenEnhancer tokenEnhancer() {
        TokenEnhancerChain chain = new TokenEnhancerChain();
        chain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter(), new UserIdAdditionalInformation(userAccountService)));
        return chain;
    }

    // 因为要支持老版本登录，需要创建Token，故这里只能配置jks，不需要创建token则只配公钥即可
    private JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        KeyStoreKeyFactory factory = new KeyStoreKeyFactory(new ClassPathResource(JKS_PATH), KEY_PASS.toCharArray());
        converter.setKeyPair(factory.getKeyPair(KEY_STORE_ALIAS));
        converter.setAccessTokenConverter(accessTokenConverter());
        return converter;
    }

    // 因为要支持老版本登录，这里不能只设置公钥
//    @Bean
//    @Primary
//    public JwtAccessTokenConverter jwtAccessTokenConverter() {
//        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
//        String publicKey;
//        try {
//            publicKey = FileUtil.readString(new ClassPathResource(PUBLIC_KEY_PATH).getURL(), StandardCharsets.UTF_8);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//        converter.setVerifier(new RsaVerifier(publicKey));
//        converter.setAccessTokenConverter(accessTokenConverter());
//        return converter;
//    }

    // 解决SecurityUtils.getUser()错误的问题
    public AccessTokenConverter accessTokenConverter() {
        DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
        MyDefaultAccessTokenConverter userAuthenticationConverter = new MyDefaultAccessTokenConverter();
        // jwt token解析，使用userDetailsService select -> username 的额外信息，该项不需要
        // userAuthenticationConverter.setUserDetailsService(userDetailsService);
        accessTokenConverter.setUserTokenConverter(userAuthenticationConverter);
        return accessTokenConverter;
    }

}
